﻿using Application.Commons.Data;
using FrameworkCore.Constants;
using FrameworkCore.Extensions;
using FrameworkCore.Helpers;
using FrameworkCore.Models;
using MediatR;
using Microsoft.Extensions.Configuration;
using NM.Module.Manager.API.EventHandlers;
using System.ComponentModel.DataAnnotations;

namespace NM.Module.Manager.API.Commands.UnInstall;

#nullable disable

/// <summary>
/// 模块卸载
/// </summary>
public class UnInstallModulerCommand : IRequest<Result<bool>>
{
    /// <summary>
    /// 模块主键
    /// </summary>
    [Required(ErrorMessage = "模块主键必传")]
    public long ModulerId { get; set; }

    /// <summary>
    /// 卸载成功后是否重启，默认不重启
    /// </summary>
    public bool RestartAfterInstall { get; set; } = false;
}

/// <summary>
/// 处理程序
/// </summary>
public class UnInstallModulerCommandHandler : IRequestHandler<UnInstallModulerCommand, Result<bool>>
{
    private readonly ApplicationDbContext _context;
    private readonly IMediator _mediator;

    public UnInstallModulerCommandHandler(ApplicationDbContext context, IMediator mediator)
    {
        _context = context;
        _mediator = mediator;
    }

    public async Task<Result<bool>> Handle(UnInstallModulerCommand request, CancellationToken cancellationToken)
    {
        var moduler = await _context.Modulers.FindAsync(request.ModulerId);
        ExceptionHelper.ThrowIfNull(moduler, "模块不存在");

        string unInstallModulerPath = Path.Combine(ApplicationPartManagerExtensions
            .GetModulesDirectory(ConfigurationsExtensions.GetGlobalSection<List<string>>(GlobalConstants.ModulePathsKey)),
            GlobalConstants.PackagesFolderName);

        unInstallModulerPath = Path.Combine(unInstallModulerPath, moduler.Name);

        moduler.AddDomainEvent(new InstallEvent(request.RestartAfterInstall));
        _context.Modulers.Remove(moduler);
        var count = await _context.SaveChangesAsync(cancellationToken);
        if (count > 0 && File.Exists(unInstallModulerPath))
        {
            File.Delete(unInstallModulerPath);
        }
        ExceptionHelper.ThrowIfTrue(count == 0, "卸载失败");

        return await Result<bool>.SucceedAsync(true);
    }
}